<template>
  <div class="detail-container">
    <el-skeleton :rows="5" animated v-if="loading" />
    <div v-else class="detail-content">
      <div class="detail-header" v-if="hasEditableFields">
        <el-button type="primary" @click="toggleEdit" class="edit-toggle-button">
          {{ isEditing ? '取消编辑' : '编辑' }}
        </el-button>
      </div>

      <el-form :model="detailData" :rules="rules" ref="formRef">
        <el-descriptions :column="2" :border="true" size="medium" class="detail-descriptions">
          <template v-for="(column, index) in tableColumnList">
            <!-- 非文本域类型 -->
            <el-descriptions-item v-if="column.editType !== 'textarea'" :key="index" :label="column.attributeLabel"
              label-class-name="detail-label" content-class-name="detail-value">
              <div v-if="!isEditing || column.unUpdatable" class="value-content"
                :style="{ whiteSpace: column.editType === 'textarea' ? 'pre-wrap' : 'normal' }">
                {{ formatColumnValue(detailData, column) || '暂无数据' }}
              </div>
              <el-form-item v-else :prop="column.attributeName" :rules="column.rules">
                <el-input v-if="column.editType === 'text'" 
                  v-model="nestedValues[column.attributeName]"
                  :placeholder="'请输入' + column.attributeLabel" clearable />

                <el-select v-else-if="column.editType === 'select'" 
                  v-model="nestedValues[column.attributeName]"
                  :placeholder="'请选择' + column.attributeLabel" clearable filterable style="width: 100%">
                  <el-option v-for="option in column.selectOperation?.options || []" :key="option.value"
                    :label="option.label" :value="option.value" :disabled="option.disabled" />
                </el-select>

                <el-input v-else-if="column.editType === 'password'" 
                  v-model="nestedValues[column.attributeName]"
                  type="password" :placeholder="'请输入' + column.attributeLabel" clearable />

                <el-input v-else-if="column.editType === 'number'" 
                  v-model="nestedValues[column.attributeName]"
                  :placeholder="column.attributeTooltip" clearable style="width: 100%; min-width: 120px"
                  @input="onNumberInput(column.attributeName, /\D/g)"></el-input>

                <el-input v-else-if="column.editType === 'email'" 
                  v-model="nestedValues[column.attributeName]"
                  type="email" :placeholder="'请输入' + column.attributeLabel" clearable />

                <el-input v-else-if="column.editType === 'url'" 
                  v-model="nestedValues[column.attributeName]"
                  type="url" :placeholder="'请输入' + column.attributeLabel" clearable />

                <el-date-picker v-else-if="column.editType === 'date'" 
                  v-model="nestedValues[column.attributeName]"
                  type="date" :placeholder="'请选择' + column.attributeLabel" clearable />

                <el-date-picker v-else-if="column.editType === 'datetime-local'" 
                  v-model="nestedValues[column.attributeName]"
                  type="datetime" :placeholder="'请选择' + column.attributeLabel" clearable />

                <el-date-picker v-else-if="column.editType === 'month'" 
                  v-model="nestedValues[column.attributeName]"
                  type="month" :placeholder="'请选择' + column.attributeLabel" clearable />

                <el-date-picker v-else-if="column.editType === 'week'" 
                  v-model="nestedValues[column.attributeName]"
                  type="week" :placeholder="'请选择' + column.attributeLabel" clearable />

                <el-time-picker v-else-if="column.editType === 'time'" 
                  v-model="nestedValues[column.attributeName]"
                  :placeholder="'请选择' + column.attributeLabel" clearable />

                <el-color-picker v-else-if="column.editType === 'color'" 
                  v-model="nestedValues[column.attributeName]"
                  :predefine-colors="[]" />
                
                <el-input v-else-if="column.editType === 'textarea'" 
                  v-model="nestedValues[column.attributeName]"
                  type="textarea" :rows="4" :placeholder="'请输入' + column.attributeLabel" />

                <el-input v-else 
                  v-model="nestedValues[column.attributeName]"
                  :placeholder="'请输入' + column.attributeLabel" clearable />
              </el-form-item>
            </el-descriptions-item>

            <!-- 文本域类型，占两列 -->
            <el-descriptions-item v-else :key="`textarea-${index}`" :label="column.attributeLabel"
              label-class-name="detail-label" content-class-name="detail-value" :span="2">
              <div v-if="!isEditing || column.unUpdatable" class="value-content" :style="{ whiteSpace: 'pre-wrap' }">
                {{ formatColumnValue(detailData, column) || '暂无数据' }}
              </div>
              <el-form-item v-else :prop="column.attributeName" :rules="column.rules">
                <el-input 
                  v-model="nestedValues[column.attributeName]"
                  type="textarea" :rows="4" :placeholder="'请输入' + column.attributeLabel" />
              </el-form-item>
              <div v-if="!isEditing || column.unUpdatable" class="extra-rows">
                <div v-for="i in 3" :key="`extra-row-${index}-${i}`" class="extra-row">
                  &nbsp;
                </div>
              </div>
            </el-descriptions-item>
          </template>
        </el-descriptions>
      </el-form>

      <div class="detail-footer">
        <el-button v-if="isEditing" type="primary" @click="confirmSave" class="save-button" :loading="saving">
          保存
        </el-button>
        <el-button type="primary" @click="closeDialog" class="close-button">
          关闭
        </el-button>
      </div>
    </div>
  </div>
</template>


<script setup lang="ts">
import { ref, watch, defineProps, defineEmits, computed } from 'vue'
import axios from 'axios'
import { MainAttributeInfoInterface } from '@/views/common/ts/Interface';
import { ElMessage, ElForm, ElMessageBox } from 'element-plus'
import { buildNestedPayload,getNestedValue} from '@/views/common/ts/CommonFunction';

const props = defineProps<{
  updateUri: string
  detailUri: string
  queryRequest: string | null
  rowId: string | number
  rowData: any
  tableColumnList: MainAttributeInfoInterface[]
  primaryKey: string
}>()


const formatColumnValue = (row: any, column: MainAttributeInfoInterface) => {
  // 1. 获取原始值（支持嵌套属性）
  const value = getNestedValue(row, column.attributeName);
  
  // 2. 优先执行列配置的格式化函数（如userSex的转换逻辑）
  if (column.extendsAttributeInfo?.formatterFunction) {
    return column.extendsAttributeInfo.formatterFunction(row, column);
  }
  
  // 3. 如果是select类型，匹配下拉选项的label（F/M→男/女）
  if (column.editType === 'select' && column.selectOperation?.options) {
    const matchOption = column.selectOperation.options.find(opt => opt.value === value);
    return matchOption?.label || value; // 匹配不到则返回原始值
  }
  
  // 4. 其他类型沿用原有的格式处理（日期、时间等）
  return formatValue(value, column.editType);
};

const emits = defineEmits(['closeDialogEvent', 'refreshData', 'updateTableRow'])

const detailData = ref<Record<string, any>>({})
const loading = ref(false)
const saving = ref(false)
const originalData = ref<Record<string, any>>({})
const isEditing = ref(false)
const formRef = ref<InstanceType<typeof ElForm>>()
const rules = ref({})



/**
 * 根据路径设置嵌套对象的值
 * @param obj 源对象
 * @param path 属性路径，如 'a.b.c'
 * @param value 新值
 */
const setNestedValue = (obj: Record<string, any>, path: string, value: any) => {
  if (!obj || !path) return;
  const keys = path.split('.');
  const lastKey = keys.pop()!;
  const parentObj = keys.reduce((o, k) => {
    if (!o[k]) o[k] = {}; 
    return o[k];
  }, obj);
  if (parentObj) {
    parentObj[lastKey] = value;
    detailData.value = { ...detailData.value };
  }
};

// 创建嵌套值的响应式对象，使用更安全的方式定义setter
const nestedValues = computed(() => {
  const values: Record<string, any> = {};
  
  props.tableColumnList.forEach(column => {
    Object.defineProperty(values, column.attributeName, {
      get: () => getNestedValue(detailData.value, column.attributeName),
      set: function(val) {  // 使用function语法确保this指向正确
        setNestedValue(detailData.value, column.attributeName, val);
        // 移除了任何可能的return语句，修复no-setter-return错误
      },
      enumerable: true
    });
  });
  
  return values;
});

const onNumberInput = (key: string, pattern: RegExp) => {
  const currentValue = getNestedValue(detailData.value, key) as string;
  if (currentValue !== null && currentValue !== undefined) {
    const newValue = currentValue.replace(pattern, '');
    setNestedValue(detailData.value, key, newValue);
  }
};

const hasEditableFields = computed(() => {
  return props.tableColumnList.some(column => !column.unUpdatable)
})

const primaryKeyName = computed(() => {
  if (props.primaryKey) {
    return props.primaryKey;
  }
  const primaryKeyColumn = props.tableColumnList.find(col => col.isPrimaryKey)
  if (primaryKeyColumn) {
    return primaryKeyColumn.attributeName;
  }
  return 'id'
})

const formatValue = (value: any, editType: string) => {
  if (value === null || value === undefined) return '';
  if (['date', 'datetime-local', 'time', 'month', 'week'].includes(editType)) {
    return new Date(value).toLocaleString();
  }
  return value;
}

const fetchDetail = async () => {
  const primaryValue = getNestedValue(props.rowData, primaryKeyName.value);
  const params: any = {
    [primaryKeyName.value]: primaryValue,
  }
  if (props.queryRequest != null) {
    const prefix = props.queryRequest;
    let primaryKeyAttributeName = prefix + "." + lastSegment(primaryKeyName.value, ".");
    params[`${prefix}.pageNum`] = 1;
    params[`${prefix}.pageSize`] = 1;
    params[primaryKeyAttributeName] = primaryValue;
    params[`${prefix}.needCountTotal`] = false;
  } else {
    params['pageNum'] = 1;
    params['pageSize'] = 1;
    params['needCountTotal'] = false;
  }

  const nestedParams = buildNestedPayload(params);
  try {
    loading.value = true;
    const response = await axios.post(props.detailUri, nestedParams);
    if (response.data && response.data.data && response.data.data.length > 0) {
      detailData.value = response.data.data[0];
      console.info("获取详情数据:", JSON.stringify(detailData.value));

      props.tableColumnList.forEach(column => {
        if (column.editType === 'number') {
          const value = getNestedValue(detailData.value, column.attributeName);
          if (value !== null && value !== undefined) {
            setNestedValue(detailData.value, column.attributeName, Number(value));
          }
        }
      })

      originalData.value = JSON.parse(JSON.stringify(detailData.value));
    } else {
      ElMessage.error('未获取到详情数据')
    }
  } catch (err: any) {
    ElMessage.error(err.message || '获取详情失败')
  } finally {
    loading.value = false
  }
}

const lastSegment = (str: string, separator: string = '.'): string => {
  if (!str || !separator) {
    return str;
  }
  const lastIndex = str.lastIndexOf(separator);
  if (lastIndex === -1) {
    return str;
  }
  return str.slice(lastIndex + separator.length);
}

const toggleEdit = () => {
  isEditing.value = !isEditing.value
  if (!isEditing.value) {
    detailData.value = JSON.parse(JSON.stringify(originalData.value))
  }
}

const confirmSave = async () => {
  if (!isEditing.value) return
  if (formRef.value) {
    await formRef.value.validate((valid) => {
      if (valid) {
        ElMessageBox.confirm(
          '确定要保存修改吗？',
          '提示',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
          }
        )
          .then(() => {
            saveChanges()
          })
          .catch(() => {
            // 用户取消
          })
      } else {
        ElMessage.error('表单验证失败，请检查输入内容')
      }
    })
  }
}

const saveChanges = async () => {
  saving.value = true
  const payload: Record<string, any> = {
    [primaryKeyName.value]: getNestedValue(detailData.value, primaryKeyName.value)
  }

  props.tableColumnList.forEach(column => {
    if (!column.unUpdatable) {
      payload[column.attributeName] = getNestedValue(detailData.value, column.attributeName);
    }
  })

  axios.post(props.updateUri, payload)
    .then((response) => {
      if (response.data && response.data.result) {
        ElMessage.success('保存成功!')
        isEditing.value = false;
        
        const newData = response.data.data;
        for (const key in newData) {
          if (newData[key] !== null && newData[key] !== undefined) {
            setNestedValue(originalData.value, key, newData[key]);
            setNestedValue(detailData.value, key, newData[key]);
          }
        }
        
        detailData.value = { ...detailData.value }
        emits('refreshData')
        emits('updateTableRow', detailData.value)
      } else {
        ElMessage.error(response.data.msg || '保存失败')
      }
    })
    .catch((err: any) => {
      ElMessage.error(err.message || '保存失败')
    })
    .finally(() => {
      saving.value = false
    })
}

watch(() => props.rowId, () => {
  isEditing.value = false
  fetchDetail()
}, { immediate: true })

const closeDialog = () => {
  emits('closeDialogEvent')
}
</script>

<style scoped>
.detail-container {
  padding: 16px;
  background-color: #fff;
  border-radius: 4px;
  max-width: 800px;
  margin: 0 auto;
}

.detail-content {
  margin-top: 8px;
}

.detail-header {
  margin-bottom: 16px;
  text-align: right;
}

.detail-footer {
  margin-top: 20px;
  text-align: center;
}

.close-button {
  width: 100px;
}

.edit-toggle-button,
.save-button {
  width: 100px;
  margin-right: 20px;
}

.value-content {
  word-break: break-word;
  min-height: 22px;
  line-height: 22px;
}

.extra-rows {
  margin-top: 8px;
}

.extra-row {
  height: 22px;
}

.el-input,
.el-textarea {
  width: 100%;
}
</style>

<style>
.detail-label {
  color: #909399 !important;
  background-color: #f5f7fa !important;
  width: 160px;
  padding: 12px 10px !important;
  line-height: 1.5;
  word-break: break-word;
  white-space: normal;
  vertical-align: top;
}

.detail-value {
  color: #606266;
  padding: 12px 10px !important;
  line-height: 1.5;
  min-width: 200px;
}

.el-descriptions__body .el-descriptions__table {
  table-layout: fixed;
}

.el-descriptions__body .el-descriptions__table td {
  word-break: break-word;
}
</style>
